package com.itheima.controller;

import com.itheima.config.RedisUtils;
import com.itheima.constant.RoomHotelConstant;
import com.itheima.entity.SysUser;
import com.itheima.constant.MessageConstant;
import com.itheima.mapper.SysUserMapper;
import com.itheima.mapper.TokenUserMapper;
import com.itheima.pojo.jo.UserInformation;
import com.itheima.pojo.jo.VerificationCode;
import com.itheima.pojo.po.UserPo;
import com.itheima.service.ISysUserService;
import com.itheima.utils.JwtUtil;
import com.itheima.utils.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

import static com.itheima.utils.JwtUtil.parseToken;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private TokenUserMapper tokenUserMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private RedisUtils redisUtils;

    /**
     * 用户注册
     *
     * @param
     * @param
     * @param
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody SysUser user) throws Exception {

        //先查询用户名和邮箱是否存在，存在则返回错误信息
        if (user.getEmail() == null || user.getUsername() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        SysUser sysUser = userService.selectUsernsmeAndEmail(user.getUsername(), user.getEmail());
        if (sysUser != null) {
            redisUtils.del(RoomHotelConstant.USER_CODE + user.getEmail());
            return Result.error(MessageConstant.ALREADY_EXISTS);
        }
        String code = redisUtils.get(RoomHotelConstant.USER_CODE + user.getEmail());
        if (!code.equals(user.getCode())) {
            redisUtils.del(RoomHotelConstant.USER_CODE + user.getEmail());
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        userService.register(user);
        return Result.success();
    }

    @GetMapping("/userInfo")
    private Result userInfo(Integer occupation){
        Map<String,Object> maps = new HashMap<>();
        if (occupation == 0){
            maps.put("roles", Arrays.asList("student"));
        }else if (occupation == 1){
            maps.put("roles", Arrays.asList("teacher"));
        }else if (occupation == 2){
            maps.put("roles", Arrays.asList("admin"));
        }
        return Result.success(maps);
    }

    /**
     * 发送邮箱验证码
     *
     * @return
     */
    @PostMapping("/code")
    public Result code(@RequestBody SysUser user) {
       String code = userService.code(user);
        return Result.success(code);
    }

    /**
     * 用户密码登陆
     *
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody SysUser users) {
        //先查询用户名是否存在，不存在则返回错误信息
        if (users.getUsername() == null || users.getPassword() == null || users.getOccupation() == null) {
            Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (redisUtils.get(RoomHotelConstant.USER_PWD_CODE + users.getCode())==null || !redisUtils.get(RoomHotelConstant.USER_PWD_CODE + users.getCode()).equals(users.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        // 判断username是账号还是手机号
        String mobileRegular = "1[3-9]\\d{9}$";
        if (users.getUsername().matches(mobileRegular)) {
            users.setMobile(users.getUsername());
            users.setUsername(null);
        }
        SysUser user = sysUserMapper.findByUsername(users);
        if (user == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(users.getPassword().getBytes()))) {
            return Result.error(MessageConstant.PASSWORD_ERROR);
        }
        // 查看用户状态是否正常
        if (user.getStatus().equals(1)) {
            return Result.error(MessageConstant.ACCOUNT_LOCKED);
        }
        redisUtils.del(RoomHotelConstant.USER_PWD_CODE + users.getCode());
        Map<String, Object> elaims = new HashMap<>();
        elaims.put("id", user.getId());
        elaims.put("username", user.getUsername());
        String token = JwtUtil.genToken(elaims);
        UserPo userPo = new UserPo();
        userPo.setToken(token);
        BeanUtils.copyProperties(user, userPo);
        tokenUserMapper.insert(token, new Date(), userPo.getId(),userPo.getOccupation());
        return Result.success(userPo);
    }

    /**
     * 验证码登陆
     *
     * @param userEmail
     * @return
     */
    @PostMapping("/codelogin")
    public Result codelogin(@RequestBody SysUser userEmail) {
        if (userEmail.getEmail() == null || userEmail.getCode() == null || userEmail.getOccupation() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (redisUtils.get(RoomHotelConstant.USER_CODE + userEmail.getEmail()) == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        SysUser email = sysUserMapper.findEmail(userEmail.getEmail());
        if (email == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        if (!redisUtils.get(RoomHotelConstant.USER_CODE + userEmail.getEmail()).equals(userEmail.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        // 查看用户状态是否正常
        if (email.getStatus().equals(1)) {
            return Result.error(MessageConstant.ACCOUNT_LOCKED);
        }
        else {
            //登陆成功，删除验证码，使当前验证码失效
            redisUtils.del(RoomHotelConstant.USER_CODE + userEmail.getEmail());
            //生成token
            Map<String, Object> elaims = new HashMap<>();
            elaims.put("id", email.getId());
            elaims.put("username", email.getUsername());
            String token = JwtUtil.genToken(elaims);
            UserPo userPo = new UserPo();
            userPo.setToken(token);
            BeanUtils.copyProperties(email, userPo);
            tokenUserMapper.insert(token, new Date(), userPo.getId(),userPo.getOccupation());
            return Result.success(userPo);
        }
    }

    /**
     * 重置密码
     *
     * @param user
     * @return
     */
    @PostMapping("/setPassword")
    public Result resetPassword(@RequestBody SysUser user) {
        if (user.getEmail() == null || user.getPassword() == null || user.getCode() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (!redisUtils.get(RoomHotelConstant.USER_CODE + user.getEmail()).equals(user.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        SysUser email = sysUserMapper.findEmail(user.getEmail());
        if (email == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        userService.reset(user);
        return Result.success();
    }

    @PostMapping("/verificationCode")
    @ApiOperation("获取验证码")
    public Result verificationCode(@RequestBody VerificationCode verif) {
        System.out.println(verif);
        if (verif.getCode() == null || verif.getEmail() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (!redisUtils.get(RoomHotelConstant.USER_CODE + verif.getEmail()).equals(verif.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        return Result.success();
    }

    @PostMapping("/bindPhone")
    @ApiOperation("修改手机号")
    public Result bindPhone(@RequestBody VerificationCode exitPhone) {
        if (exitPhone.getCode() == null || exitPhone.getData() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (!redisUtils.get(RoomHotelConstant.USER_CODE + exitPhone.getEmail()).equals(exitPhone.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        SysUser user = sysUserMapper.selectPhone(exitPhone.getData());
        if (user != null) {
            return Result.error(MessageConstant.ALREADY_PHONE);
        }
        sysUserMapper.updatePhone(exitPhone.getData(), exitPhone.getEmail());
        SysUser sysUser = sysUserMapper.findEmail(exitPhone.getEmail());
        redisUtils.del(RoomHotelConstant.USER_CODE + exitPhone.getEmail());
        return Result.success(sysUser);
    }

    @PostMapping("/changeAddress")
    @ApiOperation("修改邮箱")
    public Result changeAddress(@RequestBody VerificationCode exitEmail) {
        if (exitEmail.getCode() == null || exitEmail.getData() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        if (!redisUtils.get(RoomHotelConstant.USER_CODE + exitEmail.getEmail()).equals(exitEmail.getCode())) {
            return Result.error(MessageConstant.ACCOUNT_NOT_CODE);
        }
        SysUser user = sysUserMapper.findEmail(exitEmail.getData());
        if (user != null) {
            return Result.error(MessageConstant.ALREADY_EMAIL);
        }
        sysUserMapper.updateEmail(exitEmail.getData());
        SysUser sysUser = sysUserMapper.findEmail(exitEmail.getEmail());
        redisUtils.del(RoomHotelConstant.USER_CODE + exitEmail.getEmail());
        return Result.success(sysUser);
    }

    @PostMapping("/exitPassword")
    @ApiOperation("修改密码")
    public Result exitPassword(@RequestBody VerificationCode exitEmail) {
        if (exitEmail.getPassword() == null || exitEmail.getEmail() == null) {
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        SysUser user = sysUserMapper.findEmail(exitEmail.getEmail());
        if (user == null) {
            return Result.error(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        sysUserMapper.exitPassword(exitEmail.getEmail(), DigestUtils.md5DigestAsHex(exitEmail.getPassword().getBytes()));
        return Result.success();
    }

    @PostMapping("/changeInformation")
    @ApiOperation("个人信息")
    public Result changeInformation(@RequestBody UserInformation userInfo) {
        if (userInfo.getEmail() == null || (userInfo.getUsername() == null && userInfo.getMobile() == null
                && userInfo.getHeadUrl() == null && userInfo.getRealName() == null && userInfo.getSex() == null
                && userInfo.getUpdater() == null)){
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        sysUserMapper.updateChange(userInfo);
            return Result.success();
    }

    @GetMapping("/delectUser")
    @ApiOperation("删除个人信息")
    public Result delectUser(Integer id) {
        if (id == null){
            return Result.error(MessageConstant.ACCOUNT_CHANSHU);
        }
        //TODO
        return Result.success();
    }

}
